import pyautogui
import pygetwindow as gw
import time
import psutil
import numpy as np
from PIL import Image
from utils import press_key, click_mouse, activate_window
from dotenv import load_dotenv
import os
import subprocess

# 1. 把 .env 读到环境变量
load_dotenv()          # 默认找当前目录下的 .env



pyautogui.FAILSAFE = True  # 鼠标移到左上角停止脚本
pyautogui.PAUSE = 0.5  # 每操作暂停 0.5s

class DNFLauncher:
    def __init__(self):
        self.launcher_title = "神幻DOF"  # 调整为实际标题
        self.game_title = "Dungeon & Fighter"    # 游戏窗口标题
        self.timeout = 30  # 等待超时（秒）
        self.last_start_time = None
    
    def choose_character(self, character_index: int):
        """选择角色"""
        x_position = 155
        y_position = 80
        width = 750
        height = 420
        character_matrix = [6, 2]  # 行数和列数

        # 计算每个角色的宽度和高度
        character_width = width / character_matrix[0]
        character_height = height / character_matrix[1]

        # 根据索引计算角色的行列位置
        row = character_index // character_matrix[0]  # 行索引
        col = character_index % character_matrix[0]   # 列索引

        # 计算角色的左上角坐标
        character_x = x_position + col * character_width
        character_y = y_position + row * character_height

        # 计算角色的中心坐标
        center_x = character_x + character_width / 2
        center_y = character_y + character_height / 2

        click_mouse(center_x, center_y, clicks=3)

        return

    def click_button_by_image(self, image_path, confidence=0.8):
        """通过图像匹配点击按钮"""
        try:
            location = pyautogui.locateOnScreen(image_path, confidence=confidence)
            if location:
                center = pyautogui.center(location)
                print(f"准备点击: {image_path}")
                click_mouse(center.x, center.y, clicks=3)

                print(f"已点击按钮: {image_path}")
                return True
            else:
                print(f"未找到按钮: {image_path}")
                return False
        except Exception as e:
            print(f"点击失败: {e}")
            return False

    def wait_for_image(self, image_path, timeout=None, confidence=0.8):
        """等待窗口出现"""
        timeout = timeout or self.timeout
        start = time.time()
        while time.time() - start < timeout:
            try:
                location = pyautogui.locateOnScreen(image_path, confidence=confidence)
                if location:
                    print(f"image 已出现: {location}, {image_path}")
                    return True
            except:
                pass
            finally:
                time.sleep(1)
        print(f"超时未出现: {image_path}")
        return False

    def wait_for_window(self, title, timeout=None):
        """等待窗口出现"""
        timeout = timeout or self.timeout
        start = time.time()
        while time.time() - start < timeout:
            if gw.getWindowsWithTitle(title):
                print(f"窗口已出现: {title}")
                return True
            time.sleep(1)
        print(f"超时未出现: {title}")
        return False

    def close_game_on_error(self):
        """异常时关闭游戏"""
        for proc in psutil.process_iter(['pid', 'name']):
            if 'dnf' in proc.info['name'].lower() or '地下城' in proc.info['name']:
                proc.kill()
                print("已强制关闭游戏进程")
                return True
        return False

    def close_starter(self):
        """异常时关闭游戏"""
        for proc in psutil.process_iter(['pid', 'name']):
            if 'dnf' in proc.info['name'].lower() or '神幻' in proc.info['name'].lower() or '登陆器' in proc.info['name']:
                proc.kill()
                print("已强制关闭游戏进程")
                return True
        return False
    
    def launch_game(self, character_index: int=0):
        """完整启动流程"""
        print("开始 DNF 启动自动化...")


        # 检测游戏是否已经启动
        if self.wait_for_window(self.game_title, timeout=5):
            activate_window(self.game_title)
            if self.wait_for_image('data/game_market.png'):
                print("游戏已经启动")
                return
            
        force_restart = False
        if not self.last_start_time:
            self.last_start_time = time.time()
        else:
            if time.time() - self.last_start_time < 300:
                print(f"距离上次启动不足 300 秒，重启 {self.launcher_title}")
                self.close_starter()
                time.sleep(5)
                force_restart = True
        
        # 0 检测游戏窗口有没有启动
        windows = gw.getWindowsWithTitle(self.launcher_title)
        if not windows:
            #  启动 launcher_title
            print(f"未找到窗口: {self.launcher_title}")
            self.close_starter()
            # 2. 直接 os.getenv 拿
            DOF_PATH = os.getenv('DOF_PATH')
            print(f"DOF_PATH: {DOF_PATH}")
            if not DOF_PATH:
                print("未配置 DOF_PATH 环境变量")
                raise ValueError("未配置 DOF_PATH 环境变量")
            subprocess.Popen(DOF_PATH)
            time.sleep(20)


        if force_restart:
            # 等待6分钟, 可能完成更新
            time.sleep(360)

        # 1. 激活启动器
        activate_window(self.launcher_title)
        launcher = activate_window(self.launcher_title)
        if not launcher:
            print("启动器未运行，请手动启动")
            return

        # 2. 点击"登录游戏"按钮（假设截图文件: login_button.png）  
        
        time.sleep(1)
        press_key("enter")
        self.last_start_time = time.time()

        time.sleep(5)
        # 3. 等待游戏窗口启动
        if not self.wait_for_window(self.game_title, timeout=180):
            print("游戏启动超时")
            self.close_game_on_error()
            return

        time.sleep(30)
        # choose channel
        self.wait_for_image('data/choose_channel.png', timeout=300)
        # 4. 激活游戏窗口
        # press start
        click_mouse(488, 549, clicks=3)

        # 5. 点击频道按钮（假设截图: channel_button.png）
        time.sleep(1)  # 加载延迟
        self.wait_for_image('data/choose_character.png')
        self.choose_character(character_index)

        self.click_button_by_image('data/choose_character.png')

        # 进入游戏
        time.sleep(2)
        self.wait_for_image('data/game_market.png')

        time.sleep(5)
        # 自动拾取
        press_key("alt+q")

        time.sleep(0.1)
        # 补充疲劳
        press_key("1")

        print("游戏启动完成！")
        # 异常监控（可选后台线程）
        # threading.Thread(target=self.monitor_crash).start()

    def goto_room(self):
        # 点击进入房间
        print("准备进入房间")
        time.sleep(1)
        press_key("alt+1")
        time.sleep(2)
        press_key("right", 5)

        self.wait_for_image('data/abyss.png')
        time.sleep(1)

        flag = True

        for _ in range(10):
            if flag:
                print("f11")
                press_key("f11")
            else:
                print("mouse")
                click_mouse(883, 548, clicks=3)
            
            flag = not flag
            time.sleep(1)
            if self.wait_for_image('data/at_abyss.png',timeout=0.1):
                print("进入深渊模式")
                break
            time.sleep(1)
        else:
            raise "未找到 abyss"
        
        click_mouse(696, 238, clicks=5)
        time.sleep(5)

        print("已进入房间")
    def monitor_crash(self):
        """后台监控异常（简化版）"""
        while True:
            if not gw.getWindowsWithTitle(self.game_title):
                print("检测到游戏异常，已关闭")
                self.close_game_on_error()
                break
            time.sleep(5)



if __name__ == "__main__":
    launcher = DNFLauncher()
    launcher.launch_game(0)
    launcher.goto_room()
    # launcher.close_game_on_error()